local zhiwei = fk.CreateSkill {

  name = "joy__zhiwei",

  tags = {  },

}



zhiwei:addEffect(fk.GameStart, {
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhiwei.name) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(zhiwei.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(zhiwei.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from==player and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, true, true)
      if #to > 0 then
        event:setCostData(self, to[1])
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,zhiwei.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        event:setCostData(self, card)
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, zhiwei.name, event:getCostData(self))
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, zhiwei.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(zhiwei.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from==player and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,zhiwei.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, zhiwei.name, "support")
          player:broadcastSkillInvoke(zhiwei.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = zhiwei.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, zhiwei.name, "drawcard")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, zhiwei.name)
    elseif event == fk.Damaged then
      local card = event:getCostData(self)[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,
})
zhiwei:addEffect(fk.TurnStart, {
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhiwei.name) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(zhiwei.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(zhiwei.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from==player and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, true, true)
      if #to > 0 then
        event:setCostData(self, to[1])
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,zhiwei.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        event:setCostData(self, card)
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, zhiwei.name, event:getCostData(self))
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, zhiwei.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(zhiwei.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from==player and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,zhiwei.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, zhiwei.name, "support")
          player:broadcastSkillInvoke(zhiwei.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = zhiwei.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, zhiwei.name, "drawcard")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, zhiwei.name)
    elseif event == fk.Damaged then
      local card = event:getCostData(self)[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,
})
zhiwei:addEffect(fk.AfterCardsMove, {
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhiwei.name) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(zhiwei.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(zhiwei.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from==player and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, true, true)
      if #to > 0 then
        event:setCostData(self, to[1])
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,zhiwei.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        event:setCostData(self, card)
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, zhiwei.name, event:getCostData(self))
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, zhiwei.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(zhiwei.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from==player and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,zhiwei.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, zhiwei.name, "support")
          player:broadcastSkillInvoke(zhiwei.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = zhiwei.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, zhiwei.name, "drawcard")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, zhiwei.name)
    elseif event == fk.Damaged then
      local card = event:getCostData(self)[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,
})
zhiwei:addEffect(fk.Damage, {
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhiwei.name) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(zhiwei.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(zhiwei.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from==player and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, true, true)
      if #to > 0 then
        event:setCostData(self, to[1])
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,zhiwei.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        event:setCostData(self, card)
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, zhiwei.name, event:getCostData(self))
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, zhiwei.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(zhiwei.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from==player and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,zhiwei.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, zhiwei.name, "support")
          player:broadcastSkillInvoke(zhiwei.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = zhiwei.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, zhiwei.name, "drawcard")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, zhiwei.name)
    elseif event == fk.Damaged then
      local card = event:getCostData(self)[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,
})
zhiwei:addEffect(fk.Damaged, {
  name = "joy__zhiwei",
  events = {fk.GameStart, fk.TurnStart, fk.AfterCardsMove, fk.Damage, fk.Damaged},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(zhiwei.name) then
      if event == fk.GameStart then
        return true
      elseif event == fk.TurnStart then
        return player == target and player:getMark(zhiwei.name) == 0
      elseif event == fk.AfterCardsMove then
        if player.phase ~= Player.Discard then return false end
        local zhiwei_id = player:getMark(zhiwei.name)
        if zhiwei_id == 0 then return false end
        local room = player.room
        local to = room:getPlayerById(zhiwei_id)
        if to == nil or to.dead then return false end
        for _, move in ipairs(data) do
          if move.from==player and move.moveReason == fk.ReasonDiscard then
            for _, info in ipairs(move.moveInfo) do
              if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
              room:getCardArea(info.cardId) == Card.DiscardPile then
                return true
              end
            end
          end
        end
      elseif event == fk.Damage then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id
      elseif event == fk.Damaged then
        return target ~= nil and not target.dead and player:getMark(zhiwei.name) == target.id and not player:isKongcheng()
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, true, true)
      if #to > 0 then
        event:setCostData(self, to[1])
        return true
      end
      return false
    elseif event == fk.Damaged then
      local card = room:askForCard(player,1,1,false,zhiwei.name,true,".","#joy__zhiwei-give")
      if #card > 0 then
        event:setCostData(self, card)
        return true
      end
    else
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, zhiwei.name, event:getCostData(self))
    elseif event == fk.GameStart then
      room:notifySkillInvoked(player, zhiwei.name, "special")
      player:broadcastSkillInvoke(zhiwei.name)
      local targets = table.map(room:getOtherPlayers(player, false), Util.IdMapper)
      if #targets == 0 then return false end
      local to = room:askForChoosePlayers(player, targets, 1, 1, "#zhiwei-choose", zhiwei.name, false, true)
      if #to > 0 then
        room:setPlayerMark(player, zhiwei.name, to[1])
      end
    elseif event == fk.AfterCardsMove then
      local zhiwei_id = player:getMark(zhiwei.name)
      if zhiwei_id == 0 then return false end
      local to = room:getPlayerById(zhiwei_id)
      if to == nil or to.dead then return false end
      local cards = {}
      for _, move in ipairs(data) do
        if move.from==player and move.moveReason == fk.ReasonDiscard then
          for _, info in ipairs(move.moveInfo) do
            if (info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip) and
            room:getCardArea(info.cardId) == Card.DiscardPile then
              table.insertIfNeed(cards, info.cardId)
            end
          end
        end
      end
      if #cards > 0 then
        player:showCards(cards)
        if room:askForSkillInvoke(player,zhiwei.name,data,"#joy__zhiwei-discard") then
          room:notifySkillInvoked(player, zhiwei.name, "support")
          player:broadcastSkillInvoke(zhiwei.name)
          room:setPlayerMark(player, "@joy__zhiwei", to.general)
          room:moveCards({
          ids = cards,
          to = zhiwei_id,
          toArea = Card.PlayerHand,
          moveReason = fk.ReasonPrey,
          proposer = player.id,
          skillName = zhiwei.name,
          })
        end
      end
    elseif event == fk.Damage then
      room:notifySkillInvoked(player, zhiwei.name, "drawcard")
      player:broadcastSkillInvoke(zhiwei.name)
      room:setPlayerMark(player, "@joy__zhiwei", target.general)
      room:drawCards(player, 1, zhiwei.name)
    elseif event == fk.Damaged then
      local card = event:getCostData(self)[1]
      if not target.dead then
        room:obtainCard(target,card,false,fk.ReasonGive)
      end
    end
  end,
})
zhiwei:addEffect(fk.BuryVictim, {
  refresh_events = {fk.BuryVictim},
  can_refresh = function(self, event, target, player, data)
    return player:getMark(zhiwei.name) == target.id
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, zhiwei.name, 0)
    room:setPlayerMark(player, "@joy__zhiwei", 0)
  end,
})

return zhiwei